﻿<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Reference NStore</title>
    <link href="../../Content/Reference/Style/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="fixbar">NStore</div>
<div id="content">
    <h1>Creating domain model</h1>
    <p>Class Product</p>
<pre>
using System.Collections.Generic;
using System.Linq;
using NStore.Domain.Violations;

namespace NStore.Domain
{
    public class Product
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual string Description { get; set; }
        public virtual int Quantity { get; set; }
        public virtual Category Category { get; set; }

        public virtual ProductValidator Validator { get; set; }

        public virtual bool IsValid()
        {
            return GetRuleViolations().Count() == 0;
        }

        public virtual IEnumerable&lt;RuleViolation&gt; GetRuleViolations()
        {
            return Validator.GetRuleViolations(this);
        }
    }
}
</pre>
<p>Class ProductValidator</p>
<pre>
using System;
using System.Collections.Generic;
using System.Linq;

namespace NStore.Domain.Violations
{
    public class ProductValidator
    {
        private readonly IEnumerable&lt;Product&gt; _products;

        public ProductValidator(IEnumerable&lt;Product&gt; products)
        {
            _products = products;
        }

        public virtual IEnumerable&lt;RuleViolation&gt; GetRuleViolations(Product product)
        {
            if (String.IsNullOrEmpty(product.Name))
                yield return new RuleViolation("Name required", "Name");

            Product productFounded = _products.FirstOrDefault(item =&gt; item.Name.Equals(product.Name));
            if (productFounded != null)
                yield return new RuleViolation(String.Format("Name duplicated in product with id : {0}", productFounded.Id), "Name");
        }
    }
}

</pre>
<p>Class RuleViolation</p>
<pre>
namespace NStore.Domain.Violations
{
    public class RuleViolation
    {
        public string ErrorMessage { get; set; }
        public string PropertyName { get; set; }
        
        public RuleViolation(string errorMessage, string propertyName)
        {
            ErrorMessage = errorMessage;
            PropertyName = propertyName;
        }
    }
}
</pre>

<p>NStore.Domain.Tests.ProductTest</p>
<pre>
[TestMethod]
public void ProductInstance_CallConstructor_NotInitializeValidator()
{
    Assert.IsNull(new Product().Validator);
}
</pre>
<pre>
[TestMethod]
public void ProductInstance_CallOnIsValid_ShouldCallOnGetRuleViolationsOfValidatorProperty()
{
    ProductValidator mockProductValidator = MockRepository.GenerateMock&lt;ProductValidator&gt;(new List&lt;Product&gt;());
    Product product = new Product {Validator = mockProductValidator};
    mockProductValidator.Stub(m =&gt; m.GetRuleViolations(product)).Return(new List&lt;RuleViolation&gt;());

    product.IsValid();

    mockProductValidator.AssertWasCalled(p =&gt; p.GetRuleViolations(product));
}
</pre>
<pre>
[TestMethod]
public void ProductInstance_CallOnGetRuleViolations_ShouldCallOnGetRuleViolationsOfValidatorProperty()
{
    ProductValidator mockProductValidator = MockRepository.GenerateMock&lt;ProductValidator&gt;(new List&lt;Product&gt;());

    Product product = new Product { Validator = mockProductValidator };
    product.GetRuleViolations();

    mockProductValidator.AssertWasCalled(p =&gt; p.GetRuleViolations(product));
}
</pre>

<p>NStore.Infrastructure.Tests.MappingFile.ProductTest</p>

<pre>
[TestClass]
public class ProductTest : BaseTest
{
    [TestMethod]
    public void ShouldBePersistent()
    {
        SpecifyOn.Entity&lt;Product&gt;().ShouldBePersistent().MappedToTable("Products");
    }

    [TestMethod]
    public void Id_IsIdentifierProperty()
    {
        SpecifyOn.Entity&lt;Product&gt;().ShouldHaveProperty("Id").ShouldBePersistent()
            .MappedToColumn("Id")
            .MappedWithIdentifierProperty();
    }

    [TestMethod]
    public void Name_ShouldBePersistent()
    {
        SpecifyOn.Entity&lt;Product&gt;().ShouldHaveProperty("Name").ShouldBePersistent()
            .MappedToColumn("Name")
            .MappedWithLength(100)
            .MappedWithType&lt;StringType&gt;();
    }

    [TestMethod]
    public void Description_ShouldBePersistent()
    {
        SpecifyOn.Entity&lt;Product&gt;().ShouldHaveProperty("Description").ShouldBePersistent()
            .MappedToColumn("Description")
            .MappedWithLength(500)
            .MappedWithType&lt;StringType&gt;();
    }

    [TestMethod]
    public void Quantity_ShouldBePersistent()
    {
        SpecifyOn.Entity&lt;Product&gt;().ShouldHaveProperty("Quantity").ShouldBePersistent()
            .MappedToColumn("Quantity")
            .MappedWithType&lt;Int32Type&gt;();
    }

    [TestMethod]
    public void Category_ShouldBePersistent()
    {
        SpecifyOn.Entity&lt;Product&gt;().ShouldHaveProperty("Category").ShouldBePersistent()
            .MappedToColumn("Category")
            .MappedWithType&lt;PersistentEnumType&gt;();
    }
}
</pre>
</div>
<div id="footer"><hr />NStore</div>

</body>
</html>
